import random
import json
from enum import Enum
from dataclasses import dataclass
from typing import List, Dict, Tuple
import sys

class PoliticalSystem(Enum):
    NEUTRAL = "Neutral"
    SOCIALISM = "Socialism"
    CAPITALISM = "Capitalism"
    FASCISM = "Fascism"

class ActionType(Enum):
    PEACE = "Peace"
    AGGRESSION = "Aggression"
    CULTURAL = "Cultural"
    ECONOMIC = "Economic"
    ALLIANCE = "Alliance"

@dataclass
class Attributes:
    technology: float = 10.0
    education: float = 10.0
    military: float = 10.0
    economy: float = 10.0
    culture: float = 10.0
    
    def get_total_power(self) -> float:
        return (self.technology + self.education + self.military + 
                self.economy + self.culture) / 5

@dataclass
class Territory:
    name: str
    population: int
    resources: float
    development: float = 1.0

class Nation:
    def __init__(self, name: str, color: str, territories: List[Territory]):
        self.name = name
        self.color = color
        self.territories = territories
        self.attributes = Attributes()
        self.political_system = PoliticalSystem.NEUTRAL
        self.diplomatic_relations: Dict[str, float] = {}
        self.history: List[str] = []
        self.decisions_made: int = 0
        self.is_player = False
        
    def add_territory(self, territory: Territory):
        self.territories.append(territory)
        self.history.append(f"{self.name} gained {territory.name}")
        
    def lose_territory(self, territory_name: str):
        self.territories = [t for t in self.territories if t.name != territory_name]
        self.history.append(f"{self.name} lost {territory_name}")
        
    def develop_attributes(self):
        """Develop nation attributes"""
        tech_growth = random.uniform(0.5, 2.0)
        edu_growth = random.uniform(0.3, 1.5)
        mil_growth = random.uniform(0.5, 2.0)
        eco_growth = random.uniform(0.8, 2.5)
        cul_growth = random.uniform(0.2, 1.2)
        
        # Adjust growth based on political system
        if self.political_system == PoliticalSystem.SOCIALISM:
            edu_growth *= 1.5
            eco_growth *= 0.8
            mil_growth *= 0.7
        elif self.political_system == PoliticalSystem.CAPITALISM:
            eco_growth *= 1.8
            tech_growth *= 1.3
            edu_growth *= 0.9
        elif self.political_system == PoliticalSystem.FASCISM:
            mil_growth *= 2.0
            tech_growth *= 1.2
            edu_growth *= 0.6
            cul_growth *= 0.5
            
        self.attributes.technology += tech_growth
        self.attributes.education += edu_growth
        self.attributes.military += mil_growth
        self.attributes.economy += eco_growth
        self.attributes.culture += cul_growth
        
    def check_political_evolution(self):
        """Check if nation can evolve to new political system"""
        total_power = self.attributes.get_total_power()
        
        if total_power < 20:
            return PoliticalSystem.NEUTRAL
            
        # Determine political tendency based on attributes
        if self.attributes.military > self.attributes.economy * 1.5 and self.attributes.military > 25:
            return PoliticalSystem.FASCISM
        elif self.attributes.economy > self.attributes.military * 1.3 and self.attributes.economy > 25:
            return PoliticalSystem.CAPITALISM
        elif self.attributes.education > 20 and self.attributes.economy > 20:
            return PoliticalSystem.SOCIALISM
            
        return PoliticalSystem.NEUTRAL
        
    def get_ai_action(self, other_nations: List['Nation']) -> Tuple[ActionType, 'Nation']:
        """AI decision logic"""
        if not other_nations:
            return ActionType.PEACE, self
            
        # Decide action based on political system
        if self.political_system == PoliticalSystem.FASCISM:
            # Fascism tends to aggression
            weak_nations = [n for n in other_nations if n.attributes.military < self.attributes.military * 0.7]
            if weak_nations and random.random() < 0.7:
                target = random.choice(weak_nations)
                return ActionType.AGGRESSION, target
                
        elif self.political_system == PoliticalSystem.CAPITALISM:
            # Capitalism tends to economic actions
            if random.random() < 0.6:
                target = random.choice(other_nations)
                return ActionType.ECONOMIC, target
                
        elif self.political_system == PoliticalSystem.SOCIALISM:
            # Socialism tends to peace
            if random.random() < 0.8:
                return ActionType.PEACE, self
                
        # Default behavior
        action_type = random.choice(list(ActionType))
        target = random.choice(other_nations) if action_type != ActionType.PEACE else self
        return action_type, target
        
    def execute_action(self, action_type: ActionType, target: 'Nation'):
        """Execute action"""
        if action_type == ActionType.AGGRESSION:
            success = self.attributes.military > target.attributes.military * random.uniform(0.8, 1.2)
            if success and target.territories:
                lost_territory = random.choice(target.territories)
                target.lose_territory(lost_territory.name)
                self.add_territory(lost_territory)
                self.history.append(f"{self.name} successfully invaded {target.name}, gained {lost_territory.name}")
                target.history.append(f"{target.name} was invaded by {self.name}, lost {lost_territory.name}")
            else:
                self.history.append(f"{self.name} failed to invade {target.name}")
                
        elif action_type == ActionType.CULTURAL:
            if target.territories:
                target.attributes.culture += random.uniform(1, 3)
                self.history.append(f"{self.name} spread culture to {target.name}")
                
        elif action_type == ActionType.ECONOMIC:
            target.attributes.economy *= random.uniform(0.8, 0.95)
            self.attributes.economy += random.uniform(1, 2)
            self.history.append(f"{self.name} imposed economic sanctions on {target.name}")
            
        elif action_type == ActionType.ALLIANCE:
            self.diplomatic_relations[target.name] = 100.0
            target.diplomatic_relations[self.name] = 100.0
            self.history.append(f"{self.name} formed alliance with {target.name}")
            
    def get_total_population(self) -> int:
        return sum(t.population for t in self.territories)
        
    def get_total_resources(self) -> float:
        return sum(t.resources for t in self.territories)

class Game:
    def __init__(self):
        self.nations: List[Nation] = []
        self.turn = 0
        self.max_turns = 20  # Shorter for demo
        self.game_over = False
        self.winner = None
        
    def initialize_game(self):
        """Initialize game"""
        # Create initial territories
        territory_a = Territory("Red Plains", 1000000, 100)
        territory_b = Territory("Blue Highlands", 800000, 80)
        territory_c = Territory("Green Valley", 600000, 60)
        territory_d = Territory("Golden Coast", 1200000, 120)
        
        # Create nations
        nation_a = Nation("Red Republic", "Red", [territory_a, territory_c])
        nation_b = Nation("Blue Federation", "Blue", [territory_b, territory_d])
        
        # Set player control
        nation_a.is_player = True
        
        self.nations = [nation_a, nation_b]
        
        # Initialize diplomatic relations
        for nation in self.nations:
            for other in self.nations:
                if nation != other:
                    nation.diplomatic_relations[other.name] = 50.0
                    
    def player_decision_phase(self) -> Dict[str, any]:
        """Player decision phase"""
        player_nation = next(n for n in self.nations if n.is_player)
        other_nations = [n for n in self.nations if not n.is_player]
        
        print(f"\n=== {player_nation.name} Decision Phase ===")
        print(f"Current Political System: {player_nation.political_system.value}")
        print(f"Total Power: {player_nation.attributes.get_total_power():.1f}")
        print(f"Territories: {len(player_nation.territories)}")
        print(f"Population: {player_nation.get_total_population():,}")
        
        print("\nNation Attributes:")
        print(f"  Technology: {player_nation.attributes.technology:.1f}")
        print(f"  Education: {player_nation.attributes.education:.1f}")
        print(f"  Military: {player_nation.attributes.military:.1f}")
        print(f"  Economy: {player_nation.attributes.economy:.1f}")
        print(f"  Culture: {player_nation.attributes.culture:.1f}")
        
        print(f"\nAvailable Actions:")
        print("1. Develop Military")
        print("2. Develop Technology")
        print("3. Develop Education")
        print("4. Develop Economy")
        print("5. Develop Culture")
        print("6. Military Invasion")
        print("7. Cultural Spread")
        print("8. Economic Sanctions")
        
        if other_nations:
            print("9. Form Alliance")
            
        try:
            choice = input("Choose action (1-9): ").strip()
        except (EOFError, KeyboardInterrupt):
            # Auto-choose development if input fails
            choice = "1"
            
        decision = {
            'nation': player_nation,
            'choice': choice,
            'target': None
        }
        
        if choice in ['6', '7', '8', '9'] and other_nations:
            print("Choose target nation:")
            for i, nation in enumerate(other_nations, 1):
                print(f"{i}. {nation.name}")
            try:
                target_choice = input("Choose target: ").strip()
                if target_choice.isdigit() and 1 <= int(target_choice) <= len(other_nations):
                    decision['target'] = other_nations[int(target_choice) - 1]
            except (EOFError, KeyboardInterrupt):
                if other_nations:
                    decision['target'] = other_nations[0]
                
        return decision
        
    def execute_player_decision(self, decision: Dict[str, any]):
        """Execute player decision"""
        player_nation = decision['nation']
        choice = decision['choice']
        target = decision['target']
        
        if choice == '1':
            player_nation.attributes.military += random.uniform(3, 6)
            player_nation.history.append("Decided to develop military")
        elif choice == '2':
            player_nation.attributes.technology += random.uniform(3, 6)
            player_nation.history.append("Decided to develop technology")
        elif choice == '3':
            player_nation.attributes.education += random.uniform(3, 6)
            player_nation.history.append("Decided to develop education")
        elif choice == '4':
            player_nation.attributes.economy += random.uniform(3, 6)
            player_nation.history.append("Decided to develop economy")
        elif choice == '5':
            player_nation.attributes.culture += random.uniform(3, 6)
            player_nation.history.append("Decided to develop culture")
        elif choice == '6' and target:
            player_nation.execute_action(ActionType.AGGRESSION, target)
        elif choice == '7' and target:
            player_nation.execute_action(ActionType.CULTURAL, target)
        elif choice == '8' and target:
            player_nation.execute_action(ActionType.ECONOMIC, target)
        elif choice == '9' and target:
            player_nation.execute_action(ActionType.ALLIANCE, target)
            
        player_nation.decisions_made += 1
        
    def ai_turn(self):
        """AI turn"""
        ai_nations = [n for n in self.nations if not n.is_player]
        
        for ai_nation in ai_nations:
            other_nations = [n for n in self.nations if n != ai_nation]
            action_type, target = ai_nation.get_ai_action(other_nations)
            ai_nation.execute_action(action_type, target)
            
    def update_political_systems(self):
        """Update political systems"""
        for nation in self.nations:
            new_system = nation.check_political_evolution()
            if new_system != nation.political_system:
                old_system = nation.political_system.value
                nation.political_system = new_system
                nation.history.append(f"{nation.name} evolved from {old_system} to {new_system.value}")
                print(f"\n{nation.name} evolved to {new_system.value}!")
                
    def check_victory_conditions(self):
        """Check victory conditions"""
        for nation in self.nations[:]:
            if len(nation.territories) == 0:
                self.nations.remove(nation)
                print(f"\n{nation.name} has been eliminated!")
                
        if len(self.nations) == 1:
            self.winner = self.nations[0]
            self.game_over = True
            return
            
        # Check if turn limit reached
        if self.turn >= self.max_turns:
            self.game_over = True
            # Winner based on total power
            self.winner = max(self.nations, key=lambda n: n.attributes.get_total_power())
            
    def display_status(self):
        """Display game status"""
        print(f"\n{'='*50}")
        print(f"Turn {self.turn}/{self.max_turns}")
        print(f"{'='*50}")
        
        for nation in self.nations:
            print(f"\n{nation.name} ({nation.color})")
            print(f"  Political System: {nation.political_system.value}")
            print(f"  Total Power: {nation.attributes.get_total_power():.1f}")
            print(f"  Territories: {len(nation.territories)}")
            print(f"  Population: {nation.get_total_population():,}")
            print(f"  {'Player' if nation.is_player else 'AI'}")
            
    def run(self):
        """Run game"""
        print("Welcome to Nation Political Simulation Game!")
        print("You control a nation and influence its political path through attribute development.")
        print("Different political systems bring different behaviors and development paths.")
        print("Goal: Become the final victor within 20 turns!")
        
        self.initialize_game()
        
        while not self.game_over:
            self.turn += 1
            
            # Display status
            self.display_status()
            
            # Player decision phase
            if any(n.is_player for n in self.nations):
                decision = self.player_decision_phase()
                self.execute_player_decision(decision)
                
            # AI turn
            self.ai_turn()
            
            # Development phase
            for nation in self.nations:
                nation.develop_attributes()
                
            # Check political system changes
            self.update_political_systems()
            
            # Check victory conditions
            self.check_victory_conditions()
            
            if not self.game_over:
                try:
                    input("\nPress Enter to continue...")
                except (EOFError, KeyboardInterrupt):
                    break
                
        # Game over
        print(f"\nGame Over!")
        if self.winner:
            print(f"Winner: {self.winner.name}")
            print(f"Final Political System: {self.winner.political_system.value}")
            print(f"Final Total Power: {self.winner.attributes.get_total_power():.1f}")
            
        # Display history
        print(f"\nHistory:")
        for nation in self.nations:
            print(f"\n{nation.name}:")
            for event in nation.history[-5:]:  # Show last 5 events
                print(f"  - {event}")

if __name__ == "__main__":
    game = Game()
    game.run()